import random

currentRound = 1
totalRound = 30
# totalRound = 1
own: list = [
    {
        'Id': 1,
        'Name': '盘古',
        'Rank': 7,
        'From': 'OWN',
        'Position': [1, 1],
        'Hp': 3840,
        'Attack': 1000,
        'Defence': 930,
        'Speed': 960,
        'Anger': 0,
        'Hit': 100,
        'Dodge': 100,
        'Crit': 100,
        'AvoidCrit': 100,
        'Deepen': 1,
        'Reduction': 0,
        'Control': 0,
        'ImmuneControl': 0,
        'Skill1': {
            'Id': 2,
            'Name': '星火裂斩',
            'Type': 1,
            'Mode': 2,
            'Range': 9,
            'Hit': 0,
            'Crit': 0,
            'Ratio': 0.45,
        },
        'Skill2': {
            'Id': 2,
            'Name': '开天辟地',
            'Type': 1,
            'Mode': 1,
            'Range': 9,
            'Hit': 0,
            'Crit': 0,
            'Ratio': 1.45,
        },
        'MaxHp': 3840
    },
    {
        'Id': 2,
        'Name': '女娲',
        'Rank': 7,
        'From': 'OWN',
        'Position': [1, 2],
        'Hp': 3560,
        'Attack': 980,
        'Defence': 910,
        'Speed': 1000,
        'Anger': 0,
        'Hit': 100,
        'Dodge': 100,
        'Crit': 100,
        'AvoidCrit': 100,
        'Deepen': 1,
        'Reduction': 0,
        'Control': 0,
        'ImmuneControl': 0,
        'Skill1': {
            'Id': 2,
            'Name': '生生不息',
            'Type': 2,
            'Mode': 0,
            'Range': 9,
            'Hit': 0,
            'Crit': 0,
            'Ratio': 1,
        },
        'Skill2': {
            'Id': 2,
            'Name': '女娲补天',
            'Type': 2,
            'Mode': 0,
            'Range': 9,
            'Hit': 0,
            'Crit': 0,
            'Ratio': 1,
        },
        'MaxHp': 3560
    },
    {
        'Id': 3,
        'Name': '天狐仙人',
        'Rank': 7,
        'From': 'OWN',
        'Position': [1, 3],
        'Hp': 2000,
        'Attack': 490,
        'Defence': 470,
        'Speed': 520,
        'Anger': 0,
        'Hit': 100,
        'Dodge': 100,
        'Crit': 100,
        'AvoidCrit': 100,
        'Deepen': 1,
        'Reduction': 0,
        'Control': 0,
        'ImmuneControl': 0,
        'Skill1': {
            'Id': 2,
            'Name': '奉天承运',
            'Type': 2,
            'Mode': 0,
            'Range': 9,
            'Hit': 0,
            'Crit': 0,
            'Ratio': 1,
        },
        'Skill2': {
            'Id': 2,
            'Name': '女娲补天',
            'Type': 2,
            'Mode': 0,
            'Range': 9,
            'Hit': 0,
            'Crit': 0,
            'Ratio': 1,
        },
        'MaxHp': 3560
    }
]
foe: list = [
    {
        'Id': 1,
        'Name': '三寿道人11',
        'From': 'FOE',
        'Position': [1, 1],
        'Rank': 6,
        'Hp': 2880,
        'Attack': 850,
        'Defence': 690,
        'Speed': 670,
        'Anger': 0,
        'Hit': 100,
        'Dodge': 100,
        'Crit': 100,
        'AvoidCrit': 100,
        'Deepen': 1,
        'Reduction': 0,
        'Skill1': {
            'Id': 2,
            'Name': '如痴如狂',
            'Type': 1,
            'Mode': 2,
            'Range': 9,
            'Hit': 0,
            'Crit': 0,
            'Ratio': 0.45,
        },
        'Skill2': {
            'Id': 2,
            'Name': '千丝万缕剪',
            'Type': 1,
            'Mode': 1,
            'Range': 9,
            'Hit': 0,
            'Crit': 0,
            'Ratio': 1.45,
        },
        'MaxHp': 2880
    },
    # {
    #     'Id': 2,
    #     'Name': '三寿道人12',
    #     'From': 'FOE',
    #     'Position': [1, 2],
    #     'Rank': 6,
    #     'Hp': 2880,
    #     'Attack': 850,
    #     'Defence': 690,
    #     'Speed': 670,
    #     'Anger': 0,
    #     'Hit': 100,
    #     'Dodge': 100,
    #     'Crit': 100,
    #     'AvoidCrit': 100,
    #     'Deepen': 1,
    #     'Reduction': 0,
    #     'Skill1': {
    #         'Id': 2,
    #         'Name': '如痴如狂',
    #         'Type': 1,
    #         'Mode': 2,
    #         'Range': 9,
    #         'Hit': 0,
    #         'Crit': 0,
    #         'Ratio': 0.45,
    #     },
    #     'Skill2': {
    #         'Id': 2,
    #         'Name': '千丝万缕剪',
    #         'Type': 1,
    #         'Mode': 1,
    #     }
    # },
    # {
    #     'Id': 3,
    #     'Name': '三寿道人13',
    #     'From': 'FOE',
    #     'Position': [1, 3],
    #     'Rank': 6,
    #     'Hp': 2880,
    #     'Attack': 850,
    #     'Defence': 690,
    #     'Speed': 670,
    #     'Anger': 0,
    #     'Hit': 100,
    #     'Dodge': 100,
    #     'Crit': 100,
    #     'AvoidCrit': 100,
    #     'Deepen': 1,
    #     'Reduction': 0,
    #     'Skill1': {
    #         'Id': 2,
    #         'Name': '如痴如狂',
    #         'Type': 1,
    #         'Mode': 2,
    #         'Range': 9,
    #         'Hit': 0,
    #         'Crit': 0,
    #         'Ratio': 0.45,
    #     },
    #     'Skill2': {
    #         'Id': 2,
    #         'Name': '千丝万缕剪',
    #         'Type': 1,
    #         'Mode': 1,
    #     }
    # },
    # {
    #     'Id': 4,
    #     'Name': '三寿道人21',
    #     'From': 'FOE',
    #     'Position': [2, 1],
    #     'Rank': 6,
    #     'Hp': 2880,
    #     'Attack': 850,
    #     'Defence': 690,
    #     'Speed': 670,
    #     'Anger': 0,
    #     'Hit': 100,
    #     'Dodge': 100,
    #     'Crit': 100,
    #     'AvoidCrit': 100,
    #     'Deepen': 1,
    #     'Reduction': 0,
    #     'Skill1': {
    #         'Id': 2,
    #         'Name': '如痴如狂',
    #         'Type': 1,
    #         'Mode': 2,
    #         'Range': 9,
    #         'Hit': 0,
    #         'Crit': 0,
    #         'Ratio': 0.45,
    #     },
    #     'Skill2': {
    #         'Id': 2,
    #         'Name': '千丝万缕剪',
    #         'Type': 1,
    #         'Mode': 1,
    #     }
    # },
    # {
    #     'Id': 5,
    #     'Name': '三寿道人22',
    #     'From': 'FOE',
    #     'Position': [2, 2],
    #     'Rank': 6,
    #     'Hp': 2880,
    #     'Attack': 850,
    #     'Defence': 690,
    #     'Speed': 670,
    #     'Anger': 0,
    #     'Hit': 100,
    #     'Dodge': 100,
    #     'Crit': 100,
    #     'AvoidCrit': 100,
    #     'Deepen': 1,
    #     'Reduction': 0,
    #     'Skill1': {
    #         'Id': 2,
    #         'Name': '如痴如狂',
    #         'Type': 1,
    #         'Mode': 2,
    #         'Range': 9,
    #         'Hit': 0,
    #         'Crit': 0,
    #         'Ratio': 0.45,
    #     },
    #     'Skill2': {
    #         'Id': 2,
    #         'Name': '千丝万缕剪',
    #         'Type': 1,
    #         'Mode': 1,
    #     }
    # }, {
    #     'Id': 6,
    #     'Name': '三寿道人23',
    #     'From': 'FOE',
    #     'Position': [2, 3],
    #     'Rank': 6,
    #     'Hp': 2880,
    #     'Attack': 850,
    #     'Defence': 690,
    #     'Speed': 670,
    #     'Anger': 0,
    #     'Hit': 100,
    #     'Dodge': 100,
    #     'Crit': 100,
    #     'AvoidCrit': 100,
    #     'Deepen': 1,
    #     'Reduction': 0,
    #     'Skill1': {
    #         'Id': 2,
    #         'Name': '如痴如狂',
    #         'Type': 1,
    #         'Mode': 2,
    #         'Range': 9,
    #         'Hit': 0,
    #         'Crit': 0,
    #         'Ratio': 0.45,
    #     },
    #     'Skill2': {
    #         'Id': 2,
    #         'Name': '千丝万缕剪',
    #         'Type': 1,
    #         'Mode': 1,
    #     }
    # },
    # {
    #     'Id': 7,
    #     'Name': '三寿道人31',
    #     'From': 'FOE',
    #     'Position': [3, 1],
    #     'Rank': 6,
    #     'Hp': 2880,
    #     'Attack': 850,
    #     'Defence': 690,
    #     'Speed': 670,
    #     'Anger': 0,
    #     'Hit': 100,
    #     'Dodge': 100,
    #     'Crit': 100,
    #     'AvoidCrit': 100,
    #     'Deepen': 1,
    #     'Reduction': 0,
    #     'Skill1': {
    #         'Id': 2,
    #         'Name': '如痴如狂',
    #         'Type': 1,
    #         'Mode': 2,
    #         'Range': 9,
    #         'Hit': 0,
    #         'Crit': 0,
    #         'Ratio': 0.45,
    #     },
    #     'Skill2': {
    #         'Id': 2,
    #         'Name': '千丝万缕剪',
    #         'Type': 1,
    #         'Mode': 1,
    #     }
    # },
    # {
    #     'Id': 8,
    #     'Name': '三寿道人32',
    #     'From': 'FOE',
    #     'Position': [3, 2],
    #     'Rank': 6,
    #     'Hp': 2880,
    #     'Attack': 850,
    #     'Defence': 690,
    #     'Speed': 670,
    #     'Anger': 0,
    #     'Hit': 100,
    #     'Dodge': 100,
    #     'Crit': 100,
    #     'AvoidCrit': 100,
    #     'Deepen': 1,
    #     'Reduction': 0,
    #     'Skill1': {
    #         'Id': 2,
    #         'Name': '如痴如狂',
    #         'Type': 1,
    #         'Mode': 2,
    #         'Range': 9,
    #         'Hit': 0,
    #         'Crit': 0,
    #         'Ratio': 0.45,
    #     },
    #     'Skill2': {
    #         'Id': 2,
    #         'Name': '千丝万缕剪',
    #         'Type': 1,
    #         'Mode': 1,
    #     }
    # },
    # {
    #     'Id': 9,
    #     'Name': '三寿道人33',
    #     'From': 'FOE',
    #     'Position': [3, 3],
    #     'Rank': 6,
    #     'Hp': 2880,
    #     'Attack': 850,
    #     'Defence': 690,
    #     'Speed': 670,
    #     'Anger': 0,
    #     'Hit': 100,
    #     'Dodge': 100,
    #     'Crit': 100,
    #     'AvoidCrit': 100,
    #     'Deepen': 1,
    #     'Reduction': 0,
    #     'Skill1': {
    #         'Id': 2,
    #         'Name': '如痴如狂',
    #         'Type': 1,
    #         'Mode': 2,
    #         'Range': 9,
    #         'Hit': 0,
    #         'Crit': 0,
    #         'Ratio': 0.45,
    #     },
    #     'Skill2': {
    #         'Id': 2,
    #         'Name': '千丝万缕剪',
    #         'Type': 1,
    #         'Mode': 1,
    #     }
    # },

]

shotsOrder: list = []


def main():
    print('battle')
    try:
        for i in range(1, totalRound + 1):
            print(f'当前回合 {i}')
            global currentRound
            currentRound = i
            # 计算出手顺序
            calcOrder()
            # 按顺序出手
            battleShots()
            # 回合结束
            roundEnd()
    except Exception as e:
        print(e)
    finally:
        battleSettle()


# 战斗结算
def battleSettle():
    if len(foe) == 0:
        print('成功咯')
    else:
        print('失败咯')


# 计算卡牌出手顺序
def calcOrder():
    allCard: list = own + foe
    global shotsOrder
    shotsOrder = sorted(allCard, key=lambda card: card['Speed'], reverse=True)


# 顺序执行卡牌技能
def battleShots():
    for card in shotsOrder:
        # 卡牌死亡, 跳过出手
        if isDie(card):
            continue
        # 卡牌等钱怒气大于等于100，使用技能2
        if card['Anger'] >= 100:
            releaseSkill(card, card['Skill2'], True)
        else:
            releaseSkill(card, card['Skill1'])


def roundEnd():
    # 为所有存活角色增加战意
    for i in own:
        i['Anger'] = i['Anger'] + 20

    for i in foe:
        i['Anger'] = i['Anger'] + 20


# 卡牌是否阵亡
def isDie(card):
    fromType = card['From']
    if fromType == 'OWN':
        return len([item for item in own if item['Id'] == card['Id']]) == 0
    else:
        return len([item for item in foe if item['Id'] == card['Id']]) == 0


# 释放技能
def releaseSkill(card, skill, Anger=False):
    print(f"{card['Name']}释放了{skill['Name']}")
    if Anger:
        print(f"注意了{card['Name']}释放的是大招")
        card['Anger'] = 0

    skillType = skill['Type']

    if skillType == 1:
        monsters = searchAttackMonsters(card, skill)
        for monster in monsters:
            execAttack(card, monster, skill)
    elif skillType == 2:
        monsters = searchReplyMonsters(card, skill)
        for monster in monsters:
            execReply(card, monster, skill)


# 攻击寻怪策略
def searchAttackMonsters(card, skill, ):
    fromType = card['From']
    skillMode = skill['Mode']
    skillRange = skill['Range']

    if fromType == 'OWN':
        cardList = foe
    else:
        cardList = own

    if skillMode == 1:
        return getRowMonsters(card, cardList, skillRange)
    elif skillMode == 2:
        return getColMonsters(cardList, skillRange)


# 获取行英雄
def getRowMonsters(card, cardList, skillRange):
    position = card['Position']
    # 按一行拿取卡牌
    row, col = position
    # 优先拿取英雄对面的卡牌信息
    result = [item for item in cardList if item['Position'][0] == row]
    # 存在则返回
    if len(result) > 0:
        return result
    print("当前行未找到")
    # 不存在则按照第一行到最后一行的顺序先后读取
    for i in range(1, 4):
        result = [item for item in cardList if item['Position'][0] == i]
        if len(result) > 0:
            break
    # 返回行数据
    return result[: skillRange] if skillRange > 0 else result[skillRange]


# 获取列英雄
def getColMonsters(cardList, skillRange):
    if skillRange == 3:
        return [item for item in cardList if item['Position'][1] == 1]
    if skillRange == 6:
        return [item for item in cardList if item['Position'][1] == 1 or item['Position'][1] == 2]
    if skillRange == 9:
        return cardList


# 获取待恢复英雄
def searchReplyMonsters(card, skill):
    fromType = card['From']
    skillRange = skill['Range']

    if fromType == 'OWN':
        cardList = own
    else:
        cardList = foe

    return sorted(cardList, key=lambda item: item['Hp'], reverse=True)[:skillRange]


# 执行攻击
def execAttack(card, monster, skill):
    if not isHit(card, monster, skill):
        print(f"{card['Name']}没命中{monster['Name']}")
        return False
    print(f"{card['Name']}命中了{monster['Name']}")

    damage = calcDamage(card, monster, skill)
    crit = isCrit(card, monster, skill)

    if crit:
        realityDamage = damage * 2
        if monster['Hp'] < damage * 2:
            realityDamage = monster['Hp']
    else:
        realityDamage = damage
        if monster['Hp'] < damage:
            realityDamage = monster['Hp']

    monster['Hp'] = monster['Hp'] - realityDamage

    if crit:
        print(
            f"{card['Name']}暴击了{monster['Name']},造成伤害{realityDamage}, {monster['Name']}剩余血量{monster['Hp']}")
    else:
        print(
            f"{card['Name']}攻击了{monster['Name']},造成伤害{realityDamage}, {monster['Name']}剩余血量{monster['Hp']}")

    if monster['Hp'] > 0:
        # 我方卡牌出手后恢复怒气
        card['Anger'] = card['Anger'] + card['Rank']
        # 敌方卡牌未阵亡给卡牌增加怒气
        monster['Anger'] = monster['Anger'] + monster['Rank']
        return False

    fromType = monster['From']

    if fromType == 'OWN':
        global own
        own = list(filter(lambda x: x['Id'] != monster['Id'], own))

        if len(own) == 0:
            raise Exception(f'第{currentRound}回合,我方卡牌全部阵亡，战斗结束')

    else:
        global foe
        foe = list(filter(lambda x: x['Id'] != monster['Id'], foe))

        if len(foe) == 0:
            raise Exception(f'第{currentRound}回合,敌方卡牌全部阵亡，战斗结束')


# 执行恢复
def execReply(card, monster, skill):
    attackNum = round(card['Attack'] * skill['Ratio'])

    if monster['Hp'] + attackNum > monster['MaxHp']:
        replyNum = monster['MaxHp'] - monster['Hp']
    else:
        replyNum = attackNum

    monster['Hp'] = monster['Hp'] + replyNum
    print(f"{card['Name']}为{monster['Name']},恢复了{replyNum}血量, {monster['Name']}剩余血量{monster['Hp']}")


# 是否命中
def isHit(card, monster, skill):
    num = card['Hit'] / (card['Hit'] + monster['Dodge']) + 0.1 + skill['Hit'] / 1000
    return num > random.uniform(0, 1)


# 是否暴击
def isCrit(card, monster, skill):
    num = card['Crit'] / (card['Crit'] + monster['AvoidCrit']) + 0.1 + skill['Crit'] / 1000
    return num > random.uniform(0, 1)


# 计算伤害【使用优化减法公式】
def calcDamage(card, monster, skill):
    attackNum = card['Attack'] * skill['Ratio'] * (card['Deepen'] / 1000 + 1)
    defenceNum = card['Attack'] * monster['Defence'] / (1200 + monster['Defence']) * (monster['Reduction'] / 1000 + 1)
    return round(attackNum - defenceNum)
